package com.studykun.client.util;

import java.util.ArrayList;

import com.studykun.client.model.Card;

import static com.studykun.client.util.ListExtra.*;

public class CardSelector {
  private final HasSyllabus hasSyllabus_;
  private Card lastCard_ = null;
  
  public CardSelector(
      final HasSyllabus hasSyllabus) {
    hasSyllabus_ = hasSyllabus;
  }
  
  public Card getRandomCard() {
    return getRandomCard(4);
  }
  
  private Card getRandomCard(
      final int retries) {
    final ArrayList<HasCard> shortList = new ArrayList<HasCard>();
    final ArrayList<ArrayList<Card>> buckets = hasSyllabus_.getSyllabus().buckets();

    for (int i = 1; i < buckets.size() - 1; ++i) {
      for (final Card card : buckets.get(i)) {
        shortList.add(new HasCard() {
          public Card getCard() {
            return card;
          }
        });
      }
    }
    
    final int shortFall0 = Math.max(15 - shortList.size(), 0);
    final HasCard fallback = new HasCard() {
      public Card getCard() {
        final ArrayList<HasCard> shortList2 = new ArrayList<HasCard>();
        
        for (int i = 0; i < 10; ++i) {
          shortList2.add(new HasCard() {
            public Card getCard() {
              return randomFrom(buckets.get(0));
            }
          });
        }
        
        shortList2.add(new HasCard() {
          public Card getCard() {
            return randomFrom(buckets.get(4));
          }
        });
        
        final HasCard hasCard = randomFrom(shortList2);
        final Card card = hasCard.getCard();
        if (card != null) {
          return card;
        }
        
        final ArrayList<Card> fullList = new ArrayList<Card>();
        for (final ArrayList<Card> bucket : buckets) {
          fullList.addAll(bucket);
        }
        
        return randomFrom(fullList);
      }
    };
    
    for (int i = 0; i < shortFall0; ++i) {
      shortList.add(fallback);
    }
    
    final HasCard hasCard = randomFrom(shortList);
    
    final Card card = hasCard.getCard();
    
    if ((card == null || card == lastCard_) && retries > 0) {
      return getRandomCard(retries - 1);
    }
    
    return card;
  }
}
